//Crazy Intro, Copyright 2009 WiiCrazy/I.R.on of Irduco (nejat@tepetaklak.com)
//Distributed under the terms of the GNU GPL v2.0
//See http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt for more information


/* Letter displaying stuff borrowed from GRRLIB */
/*===========================================
        GRRLIB 4.0.0
        Code     : NoNameNo
        Additional Code : Crayon
        GX hints : RedShade

        Demo1 To promote ver 4.0.0
============================================
Download and Help Forum : http://grrlib.santo.fr
============================================*/
#include <GRRLIB.h>


#include <stdlib.h>
#include <math.h>
#include <wiiuse/wpad.h>
#include <gcmodplay.h> 
#include "core/syslog.h"

#include "gfx/font.h"
#include "gfx/console.h"
#include "gfx/boot.h"
#include "gfx/press.h"
#include "gfx/birthday.h"
//#include "gfx/wiimotegfx.h"
#include "music/happybirthday.h"
#include "music/elysium.h"
#include "effects.h"

/********************  Borrowed Code ***********************/
int ScrWid = 640, ScrHei=480;
int ScrMidX= 320, ScrMidY=240;

float ScrZoom;

int DataOut=0;
int NumStars=3000;
float MaxVelocity = 20.f;
float Velocity = 0.f;
float FieldExpanse = 1.5f;
float Brightness = 0.2f;
float Zoom = (3.f/2.f);

float GammaValue;


struct ROTATION
{
    float a,b,c;
    float avel,bvel,cvel;
    float aacc,bacc,cacc;
} Cam;

float BrightTable[256];

#define RangeRand(min,range) (min + (float)rand()/(float)RAND_MAX*range)


#define NBCHAR  17*9
#define SPEED   20

/********************  Borrowed Code ***********************/


/******************* My code *******************************/

syslog_instance_t *syslog;

#define TABLESIZE 240
#define HITABLESIZE 140
#define FADETABLESIZE 256
#define FADEPERIOD 255
#define HITABLEWIDTH 640.0
#define TEARTABLESIZE 120
#define MAXDISTANCE 1920

s8 * sinTab;
s8 * cosTab;
u8 * fadeTab;
u16 * tearTab;
u16 * highPresCosTab;

int tileCount;
static int ixlateStep;

static int introPhase = 0;
static int picturePhase = 0;
static int outroPhase = 0;

static int birthDayX;
static int birthDayY;

static int x;
static int y;

static int pressX;
static int pressY;


static int pressImageEffect;
static int pressImageTileWidth;
static int pressImageTileHeight;
static int pressImageTileOrdering;
static int pressImageAnimationSpeed;
static int pressImageScale;


static GRRLIB_texImg * c_press_img;




char *StrIntroEffect[] = {"none", "fadein", "bandup", "banddown", "enlarge_in", "alternate_lines", "stripes_up"};


char *StrPictureEffect[] = {"none", "wobble", "presspicfade", "enlarge", "scrollx", "enlarge_xy", "in_out_rotate", "zoominout", "sinusrotate", "fullrotate"};


char *StrOutroEffect[] = {"none", "fadeout", "alternate_lines", "bandup", "banddown"};


void effectsSetDebugInstance(syslog_instance_t *sysloginstance) 
{
	syslog = sysloginstance;
}


int convertIntroEffect(char * strEnum) 
{
	int i;
	for (i=IE_NONE; i<=IE_STRIPES_UP; i++) 
	{
		if (strcmp(StrIntroEffect[i], strEnum) == 0 )
		{
			return i;
		}
	}
	return 0;
}

int convertPictureEffect(char * strEnum) 
{
	int i;
	for (i=PE_NONE; i<=PE_FULL_ROTATE; i++) 
	{
		if (strcmp(StrPictureEffect[i], strEnum) == 0 )
		{
			return i;
		}
	}
	return 0;
}

int convertOutroEffect(char * strEnum) 
{
	int i;
	for (i=OE_NONE; i<=OE_BANDUP; i++) 
	{
		if (strcmp(StrOutroEffect[i], strEnum) == 0 )
		{
			return i;
		}
	}
	return 0;
}


void makeSinTab() 
{
	sinTab = (s8 *) malloc(TABLESIZE);
	
	int si;
	for(si=0;si<TABLESIZE;si++) 
	{
		sinTab[si] = (sin(si*2*M_PI / (TABLESIZE-1)) * 127);
	} 
}

void makeFadeTab() 
{
	fadeTab = (u8 *) malloc(FADETABLESIZE);
	
	int si;
	int dSize = FADETABLESIZE + FADETABLESIZE -1;
	for(si=0;si<FADETABLESIZE/2;si++) 
	{
		fadeTab[si] = (sin(si*M_PI / dSize) * 255);		
	} 

	for(si=FADETABLESIZE/2;si<FADETABLESIZE;si++) 
	{
		fadeTab[si] = (cos(si*M_PI / dSize) * 255);		
	} 
	
	#ifdef DEBUG
	//	int i;
	//	for (i=0;i<FADETABLESIZE;i++) {
	//		Syslog_SendFormat(syslog, SYSLOG_PRI_LOCAL0, SYSLOG_SEV_DEBUG, "Fade Tab %d", fadeTab[i]);
	//	}
	#endif
}

void makeTearTab() 
{
	//Get ourselves a high res 90 degree sinus table
	tearTab = (u16 *) malloc(TEARTABLESIZE*2);
	
	int si;
	int dTearTableSize = TEARTABLESIZE + TEARTABLESIZE;
	for(si=0;si<TEARTABLESIZE-40;si++) 
	{
		tearTab[si] = (sin(si*M_PI / dTearTableSize) * (MAXDISTANCE-1));		
	} 

	for(si<TEARTABLESIZE-40;si<TEARTABLESIZE;si++) 
	{
		tearTab[si] = MAXDISTANCE-1;		
	} 
	
	#ifdef DEBUG
		int i;
		for (i=0;i<20;i++) {
			Syslog_SendFormat(syslog, SYSLOG_PRI_LOCAL0, SYSLOG_SEV_DEBUG, "Tear Tab %x", tearTab[i*TILEHEIGHT]);
		}
	#endif
}

void makeCosTab() 
{
	cosTab = (s8 *) malloc(TABLESIZE);
	
	//f32 formax = 2*M_PI/TABLESIZE;
	int si;
	for(si=0;si<TABLESIZE;si++) 
	{
		cosTab[si] = (cos(si*2*M_PI / (TABLESIZE-1)) * 127);
	} 
}

void makeHighCosTab() 
{
	highPresCosTab = (u16 *) malloc(HITABLESIZE*2);
	
	//f32 formax = 2*M_PI/TABLESIZE;
	int dSize = HITABLESIZE + HITABLESIZE-2;
	int si;
	for(si=0;si<HITABLESIZE;si++) 
	{
		highPresCosTab[si] = (cos(si*M_PI / dSize) * HITABLEWIDTH);
	} 
	//highPresCosTab[HITABLESIZE-1] = HITABLEWIDTH;
	
	#ifdef DEBUG
	int i;
	for (i=0;i<20;i++) {
		Syslog_SendFormat(syslog, SYSLOG_PRI_LOCAL0, SYSLOG_SEV_DEBUG, "High res cos Tab %x", highPresCosTab[HITABLESIZE-20+i]);
	}
	#endif
}


void ClearScreen()
{
    GRRLIB_FillScreen(0x000000FF);
    GRRLIB_Render();
}

void ClearScreenNoRender()
{
    GRRLIB_FillScreen(0x000000FF);
}



/*********************************** INTRO FUNCTIONS *******************************************/
/*---------------------------------------------------------------------------------------------*/

int display_jpeg_intro(GRRLIB_texImg * jpeg) {

#ifdef DEBUG
	//Syslog_SendFormat(syslog, SYSLOG_PRI_LOCAL0, SYSLOG_SEV_DEBUG, "display_jpeg_intro: %x", introPhase);
#endif

	if (introPhase < 256) 
	{
		GRRLIB_DrawImg(jpeg->offsetx+x, jpeg->offsety+y, jpeg, 0, 1, 1, 0xFFFFFF00|introPhase);
		GRRLIB_Render();
		introPhase+=5;
		return 1;
	} else  {
		introPhase=0;
		return 0;
	}
}

int display_intro_fade_in(GRRLIB_texImg * jpeg, u8 speed, u8 duration) {

#ifdef DEBUG
	//Syslog_SendFormat(syslog, SYSLOG_PRI_LOCAL0, SYSLOG_SEV_DEBUG, "display_intro_fade_in: %x", introPhase);
#endif

	if (introPhase < 256) 
	{
		GRRLIB_DrawImg(jpeg->offsetx+x, jpeg->offsety+y, jpeg, 0, 1, 1, 0xFFFFFF00|introPhase);
		GRRLIB_Render();
		introPhase+=speed;
		return 1;
	} else  {
		introPhase=0;
		return 0;
	}
}

int display_intro_alternate_lines(GRRLIB_texImg * jpeg, u8 nullParam1, u8 nullParam2) {

#ifdef DEBUG
	//Syslog_SendFormat(syslog, SYSLOG_PRI_LOCAL0, SYSLOG_SEV_DEBUG, "display_intro_fade_in: %x", introPhase);
#endif
	int current;
	if (introPhase < HITABLESIZE) 
	{
		for (current=0;current<tileCount;current++) 
		{
			if (current%2) {
					GRRLIB_DrawTile(jpeg->offsetx+x + highPresCosTab[introPhase], jpeg->offsety + y + current * TILEHEIGHT, jpeg, 0, 1  , 1, 0xFFFFFFFF, current);
				}
				else {
					GRRLIB_DrawTile(jpeg->offsetx+x - highPresCosTab[introPhase], jpeg->offsety + y + current * TILEHEIGHT, jpeg, 0, 1  , 1, 0xFFFFFFFF, current);			
				}
		}

#ifdef DEBUG
	Syslog_SendFormat(syslog, SYSLOG_PRI_LOCAL0, SYSLOG_SEV_DEBUG, "alternate_lines: %d, %d ", introPhase,highPresCosTab[introPhase]);
#endif
		GRRLIB_Render();
		introPhase++;
		return 1;
	} else  {
		introPhase=0;
		return 0;
	}
}


int display_intro_enlarge_in(GRRLIB_texImg * jpeg, u8 speed, u8 duration) {

#ifdef DEBUG
	//Syslog_SendFormat(syslog, SYSLOG_PRI_LOCAL0, SYSLOG_SEV_DEBUG, "display_intro_fade_in: %x", introPhase);
#endif
	int current;
	if (introPhase <= TABLESIZE/4) 
	{
		for (current=0;current<tileCount;current++) 
		{
			GRRLIB_DrawTile(jpeg->offsetx + x, jpeg->offsety + y + current * TILEHEIGHT, jpeg, 0, 1  , 1 - cosTab[introPhase]/127.0, 0xFFFFFFFF, current);
		}

		GRRLIB_Render();
		introPhase+=speed;
		return 1;
	} else  {
		introPhase=0;
		return 0;
	}
}

/*
int display_intro_enlarge_in(GRRLIB_texImg * jpeg, u8 speed, u8 duration) {

#ifdef DEBUG
	//Syslog_SendFormat(syslog, SYSLOG_PRI_LOCAL0, SYSLOG_SEV_DEBUG, "display_intro_fade_in: %x", introPhase);
#endif
	int current;
	if (introPhase <= TABLESIZE/4) 
	{
		for (current=0;current<tileCount;current++) 
		{
			GRRLIB_DrawTile(x, current * TILEHEIGHT, jpeg, 0, 1-cosTab[introPhase]/128.0, 1 - cosTab[introPhase]/128.0, 0xFFFFFFFF, current);
		}

		GRRLIB_Render();
		introPhase+=speed;
		return 1;
	} else  {
		introPhase=0;
		return 0;
	}
}
*/

int display_intro_band_up(GRRLIB_texImg * jpeg, u8 speed, u8 nullParam) {

#ifdef DEBUG
	//Syslog_SendFormat(syslog, SYSLOG_PRI_LOCAL0, SYSLOG_SEV_DEBUG, "display_intro_band_up: %x", introPhase);
#endif

	//We have a dynamic height image and a fixed size sinus table...
	//We have tileCount tiles...
	//We have TEARTABLESIZE values for the tearing
	//So we should translate current tile height to 0-TEARTABLESIZE by stepping with ixlateStep which is TEARTABLESIZE/tileCount

	//We start with introPhase 1 because we'll use this value to flat out the offset we get from tearTable hence we can flat out the 
	//all offsets to zero when we reach introPhase = 256 which will make the final value of our tear table zero hence we'll get the full picture
	
	//Let's put the picture into the screen
	int current;
	int yPos;
	int i;
	ClearScreenNoRender();
	
	for (current=0;current<introPhase;current++) 
	{
		GRRLIB_DrawTile(jpeg->offsetx + x, jpeg->offsety + y + current*TILEHEIGHT, jpeg, 0, 1, 1, 0xFFFFFFFF, current);	
	}

	for (current=introPhase+1;current<tileCount;current++) 
	{
		//Calculate yPos for the current title... our tear table gives us the offset we should apply
		
		yPos = y + current*TILEHEIGHT + (tearTab[ixlateStep*(current-(introPhase))]);
		
		#ifdef DEBUG
			//Syslog_SendFormat(syslog, SYSLOG_PRI_LOCAL0, SYSLOG_SEV_DEBUG, "current tile : %x", current);
			//Syslog_SendFormat(syslog, SYSLOG_PRI_LOCAL0, SYSLOG_SEV_DEBUG, "yPos : %x", yPos);			
		#endif
		if ((yPos<= (jpeg->h + y - TILEHEIGHT) ) && (yPos>=0))
		{ //Display tile if it's in the display region...
			GRRLIB_DrawTile(jpeg->offsetx + x, jpeg->offsety + yPos, jpeg, 0, 1, 1, 0xFFFFFFFF, current);
		} 
	}
	GRRLIB_Render();

	introPhase++;
	if (introPhase==(tileCount+1)) 
	{
		introPhase = 0;
		return 0; //Exit
	}  else 
	{	
		return 1; //Continue
	}
}


int display_intro_stripes_up(GRRLIB_texImg * jpeg, u8 speed, u8 nullParam) {

#ifdef DEBUG
	//Syslog_SendFormat(syslog, SYSLOG_PRI_LOCAL0, SYSLOG_SEV_DEBUG, "display_intro_band_up: %x", introPhase);
#endif

	int current;
	int yPos;
	int i;
	ClearScreenNoRender();
	for (current=0;current<tileCount;current++) 
	{
		//Calculate yPos for the current title... our tear table gives us the offset we should apply
		
		yPos = y + current*TILEHEIGHT + tearTab[ixlateStep*current] / introPhase;
		
		#ifdef DEBUG
			//Syslog_SendFormat(syslog, SYSLOG_PRI_LOCAL0, SYSLOG_SEV_DEBUG, "current tile : %x", current);
			//Syslog_SendFormat(syslog, SYSLOG_PRI_LOCAL0, SYSLOG_SEV_DEBUG, "yPos : %x", yPos);			
		#endif
		if ((yPos<= (jpeg->h + y - TILEHEIGHT) ) && (yPos>=0))
		{ //Display tile if it's in the display region...
			GRRLIB_DrawTile(jpeg->offsetx + x, jpeg->offsety + yPos, jpeg, 0, 1, 1, 0xFFFFFFFF, current);
		} 
#ifdef DEBUG
	Syslog_SendFormat(syslog, SYSLOG_PRI_LOCAL0, SYSLOG_SEV_DEBUG, "stripesup: %d, %d, %d, %d ", introPhase, ixlateStep,current, tearTab[ixlateStep*current]);
#endif
		
	}
	GRRLIB_Render();
	introPhase++;
	if (introPhase==TEARTABLESIZE) 
	{
		introPhase=0;
		return 0; //Exit
	}  else 
	{	
		return 1; //Continue
	}
}



int display_intro_band_down(GRRLIB_texImg * jpeg, u8 speed, u8 nullParam) {

#ifdef DEBUG
	//Syslog_SendFormat(syslog, SYSLOG_PRI_LOCAL0, SYSLOG_SEV_DEBUG, "display_intro_band_up: %x", introPhase);
#endif

	int current;
	int yPos;
	int i;
	ClearScreenNoRender();
	
	for (current=tileCount;current>tileCount-introPhase;current--) 
	{
		GRRLIB_DrawTile(jpeg->offsetx + x, jpeg->offsety + y + current*TILEHEIGHT, jpeg, 0, 1, 1, 0xFFFFFFFF, current);	
	}

	for (current=tileCount-introPhase;current>=0;current--) 
	{
		//Calculate yPos for the current title... our tear table gives us the offset we should apply
		
		yPos = y + current*TILEHEIGHT + (tearTab[ixlateStep*current]);
		
		#ifdef DEBUG
			//Syslog_SendFormat(syslog, SYSLOG_PRI_LOCAL0, SYSLOG_SEV_DEBUG, "current tile : %x", current);
			//Syslog_SendFormat(syslog, SYSLOG_PRI_LOCAL0, SYSLOG_SEV_DEBUG, "yPos : %x", yPos);			
		#endif
		if ((yPos<= (jpeg->h + y - TILEHEIGHT) ) && (yPos>=0))
		{ //Display tile if it's in the display region...
			GRRLIB_DrawTile(jpeg->offsetx + x, jpeg->offsety + yPos, jpeg, 0, 1, 1, 0xFFFFFFFF, current);
		} 
	}
	GRRLIB_Render();

	introPhase++;
	if (introPhase==tileCount) 
	{
		introPhase=0;
		return 0; //Exit
	}  else 
	{	
		return 1; //Continue
	}
}

/*---------------------------------------------------------------------------------------------*/
/*********************************** INTRO FUNCTIONS *******************************************/




/*********************************** OUTRO FUNCTIONS *******************************************/
/*---------------------------------------------------------------------------------------------*/

int display_jpeg_outro_fadeout(GRRLIB_texImg * jpeg, u8 speed, u8 nullParam) {
	
	if (outroPhase < 256) 
	{
		GRRLIB_DrawImg(jpeg->offsetx+x, jpeg->offsety+y, jpeg, 0, 1, 1, 0xFFFFFF00|(255-outroPhase));
		//AUDIO_SetStreamVolRight(255-outroPhase);
		//AUDIO_SetStreamVolLeft(255-outroPhase);

		GRRLIB_Render();
		outroPhase+=speed;
		return 1;
	} else  {
		outroPhase=0;
		return 0;
	}
	
}

u8* tex_scrTmp;

int display_jpeg_outro_snap_fadeout(GRRLIB_texImg * jpeg, u8 speed, u8 nullParam) {
	if (outroPhase == 0) 
	{
	    tex_scrTmp = GRRLIB_ScreenCap();
		jpeg->data = tex_scrTmp;
	}
	if (outroPhase < 256) 
	{
		GRRLIB_DrawImg(0, 0,  jpeg, 0, 1, 1, 0xFFFFFF00|(255-outroPhase));
		//AUDIO_SetStreamVolRight(255-outroPhase);
		//AUDIO_SetStreamVolLeft(255-outroPhase);

		GRRLIB_Render();
		outroPhase+=speed;
		return 1;
	} else  {
		outroPhase=0;
		return 0;
	}
	
}

int display_outro_alternate_lines(GRRLIB_texImg * jpeg, u8 nullParam1, u8 nullParam2) {

#ifdef DEBUG
	//Syslog_SendFormat(syslog, SYSLOG_PRI_LOCAL0, SYSLOG_SEV_DEBUG, "display_intro_fade_in: %x", introPhase);
#endif
	int current;
	if (outroPhase < HITABLESIZE) 
	{
		for (current=0;current<tileCount;current++) 
		{
			if (current%2) {
					GRRLIB_DrawTile(jpeg->offsetx + x + highPresCosTab[HITABLESIZE-outroPhase], jpeg->offsety + y + current * TILEHEIGHT, jpeg, 0, 1  , 1, 0xFFFFFFFF, current);
				}
				else {
					GRRLIB_DrawTile(jpeg->offsetx + x - highPresCosTab[HITABLESIZE-outroPhase], jpeg->offsety + y + current * TILEHEIGHT, jpeg, 0, 1  , 1, 0xFFFFFFFF, current);			
				}
		}
#ifdef DEBUG
	Syslog_SendFormat(syslog, SYSLOG_PRI_LOCAL0, SYSLOG_SEV_DEBUG, "alternate_lines: %d, %d ", outroPhase,highPresCosTab[HITABLESIZE-outroPhase]);
#endif

		GRRLIB_Render();
		outroPhase++;
		return 1;
	} else  {
		ClearScreen();
		outroPhase=0;
		return 0;
	}
}

/*---------------------------------------------------------------------------------------------*/
/*********************************** OUTRO FUNCTIONS *******************************************/


/*********************************** PICTURE FUNCTIONS *****************************************/
/*---------------------------------------------------------------------------------------------*/


int pressPicIndex = 0;
int pressPicProgress = 0;
int increment = 1;

int do_press_pic_stuff(GRRLIB_texImg * pressPicImage,int fadePhase, int posX, int posY) 
{
	if (pressImageEffect==PI_FADEINOUT) 
	{
		GRRLIB_DrawImg(posX, posY, pressPicImage, 0, pressImageScale, pressImageScale, 0xFFFFFF00|(fadeTab[fadePhase]));		
	}
	else {
		int pressPicTileCount = (pressPicImage->nbtilew) * (pressPicImage->nbtileh);
		int usedIndex;
		
		if (pressImageTileOrdering == TO_FORWARD_BACKWARD) 
		{
			usedIndex = pressPicIndex;
		} else if (pressImageTileOrdering == TO_FORWARD) 
		{
			usedIndex = pressPicIndex;
		} else if (pressImageTileOrdering == TO_BACKWARD) 
		{
			usedIndex = pressPicTileCount - (pressPicIndex + 1);
		}
		
		u32 color;
		if (pressImageEffect == PI_COMBINED) 
		{
			color = 0xFFFFFF00|(fadeTab[fadePhase]);
		} 
		else 
		{
			color = 0xFFFFFFFF;
		}
		
		GRRLIB_DrawTile(posX, posY, pressPicImage, 0, pressImageScale, pressImageScale, color, pressPicIndex);
	
		pressPicProgress++;
		if ((pressPicProgress%pressImageAnimationSpeed) == 0) 
		{
			pressPicIndex = pressPicIndex+increment;
			
			if (pressImageTileOrdering == TO_FORWARD_BACKWARD) 
			{			
				if ((pressPicIndex==pressPicTileCount) || (pressPicIndex == 0))
				{
					increment = 0-increment;
					pressPicIndex = pressPicIndex+increment;
				} 
			} else 
			{
				if (pressPicIndex == pressPicTileCount) 
				{
					pressPicIndex = 0;
				}
			}
			
			
		}
		
		if (pressPicProgress>200) 
		{
			pressPicProgress = 0;
		}
	}

}


int display_jpeg(GRRLIB_texImg * jpeg) {	
	GRRLIB_DrawImg(jpeg->offsetx+x, jpeg->offsety+y, jpeg, 0, 1, 1, 0xFFFFFFFF);
	GRRLIB_Render();		
}

//static int alternate = 0;
int display_with_press_pic_fade(GRRLIB_texImg * jpeg, GRRLIB_texImg * pressPicImage, u8 fadeSpeed, u8 nullParam) {	
	GRRLIB_DrawImg(jpeg->offsetx+x, jpeg->offsety+y, jpeg, 0, 1, 1, 0xFFFFFFFF);
	
	do_press_pic_stuff(pressPicImage, picturePhase, pressX, pressY);				
	
	//GRRLIB_DrawImg(pressX, pressY, c_press_img, 0, 1, 1, 0xFFFFFF00|(fadeTab[picturePhase]));	
	
	GRRLIB_Render();		
	
	picturePhase+=fadeSpeed;
	if (picturePhase>=FADETABLESIZE) 
	{
		picturePhase = picturePhase%FADETABLESIZE;
		//alternate = 128 - alternate;
	}	
	
}

//static int alternate = 0;
int display_picture_scrollx(GRRLIB_texImg * jpeg, u8 speed, u8 nullParam) {	

	int current;
	for (current=0;current<tileCount;current++) 
	{
		GRRLIB_DrawTile(sinTab[picturePhase] + jpeg->offsetx+x, jpeg->offsety+y + current * TILEHEIGHT, jpeg, 0, 1, 1, 0xFFFFFFFF, current);
	}
	
	GRRLIB_Render();	
	
	picturePhase+=speed;
	if (picturePhase==TABLESIZE) 
	{
		picturePhase = 0;
		//alternate = 128 - alternate;
	}	
	
}

int display_picture_wobble(GRRLIB_texImg * jpeg, u8 speed, u8 widthDiv) {	

	int current;
	for (current=0;current<tileCount;current++) 
	{
		GRRLIB_DrawTile((sinTab[(picturePhase + current)%TABLESIZE]/widthDiv) + jpeg->offsetx+x, jpeg->offsety+y + current * TILEHEIGHT, jpeg, 0, 1, 1, 0xFFFFFFFF, current);
	}
	
	GRRLIB_Render();	
	
	picturePhase+=speed;
	picturePhase=picturePhase % TABLESIZE;
	
}


int display_picture_enlarge(GRRLIB_texImg * jpeg, u8 speed, u8 nullParam) {	

	int current;

	for (current=0;current<tileCount;current++) 
	{
		//GRRLIB_DrawTile(x, y + current * TILEHEIGHT, jpeg, 0, 1- sinTab[picturePhase]/128.0, 1, 0xFFFFFFFF, current);
		GRRLIB_DrawTile(jpeg->offsetx+x, jpeg->offsety+y + current * TILEHEIGHT, jpeg, 0, sinTab[picturePhase]/128.0, 1, 0xFFFFFFFF, current);
	}
	GRRLIB_Render();	
	
	picturePhase+=speed;
	picturePhase=picturePhase % TABLESIZE;
	
}

int display_picture_enlarge_xy(GRRLIB_texImg * jpeg, u8 speed, u8 nullParam) {	

	int current;

	for (current=0;current<tileCount;current++) 
	{
		//GRRLIB_DrawTile(x, y + current * TILEHEIGHT, jpeg, 0, 1 - sinTab[picturePhase]/128.0, 1 - sinTab[picturePhase]/128.0, 0xFFFFFFFF, current);
		GRRLIB_DrawTile(jpeg->offsetx + x, jpeg->offsety + y + current * TILEHEIGHT, jpeg, 0, sinTab[picturePhase]/128.0, sinTab[picturePhase]/128.0, 0xFFFFFFFF, current);
	}
	GRRLIB_Render();	
	
	picturePhase+=speed;
	picturePhase=picturePhase % TABLESIZE;
	
}

int display_picture_zoom_in_out_rotate(GRRLIB_texImg * jpeg, u8 speed, u8 alphadistance) {	

	int current;
	if (alphadistance) {	
		//GRRLIB_DrawImg(x, y, jpeg, cosTab[picturePhase]/3, 1 - sinTab[picturePhase]/128.0, 1 - sinTab[picturePhase]/128.0, 0xFFFFFF10|abs(cosTab[picturePhase]));
		GRRLIB_DrawImg(jpeg->offsetx+x, jpeg->offsety+y, jpeg, cosTab[picturePhase]/3, sinTab[picturePhase]/128.0, sinTab[picturePhase]/128.0, 0xFFFFFF10|abs(cosTab[picturePhase]));
	} else 
	{
		//GRRLIB_DrawImg(x, y, jpeg, cosTab[picturePhase]/3, 1 - sinTab[picturePhase]/128.0, 1 - sinTab[picturePhase]/128.0, 0xFFFFFFFF);
		GRRLIB_DrawImg(jpeg->offsetx+x, jpeg->offsety+y, jpeg, cosTab[picturePhase]/3, sinTab[picturePhase]/128.0, sinTab[picturePhase]/128.0, 0xFFFFFFFF);
	}
	GRRLIB_Render();	
	
	picturePhase+=speed;
	picturePhase=picturePhase % TABLESIZE;
	
}

int display_picture_zoominout(GRRLIB_texImg * jpeg, u8 speed, u8 alphadistance) {	

	int current;
	if (alphadistance) {
		GRRLIB_DrawImg(jpeg->offsetx+x, jpeg->offsety+y, jpeg, 0, 1 - sinTab[picturePhase]/128.0, 1 - sinTab[picturePhase]/128.0, 0xFFFFFFFF);
	} else 
	{
		GRRLIB_DrawImg(jpeg->offsetx+x, jpeg->offsety+y, jpeg, 0, 1 - sinTab[picturePhase]/128.0, 1 - sinTab[picturePhase]/128.0, 0xFFFFFF10|sinTab[picturePhase]);	
	}
	GRRLIB_Render();	
	
	picturePhase+=speed;
	picturePhase=picturePhase % TABLESIZE;
	
}

static int fadePhase = 0;

int display_picture_sinusrotate(GRRLIB_texImg * jpeg,GRRLIB_texImg * pressPicImage, u8 speed, u8 fadeSpeed) {	

	int current;
	GRRLIB_DrawImg(jpeg->offsetx+x, jpeg->offsety+y, jpeg, sinTab[picturePhase], 1, 1, 0xFFFFFFFF);
	do_press_pic_stuff(pressPicImage, fadePhase, pressX, pressY);	

	GRRLIB_Render();	
	
	picturePhase+=speed;
	picturePhase=picturePhase % TABLESIZE;
	fadePhase+=fadeSpeed;
	fadePhase = fadePhase % FADETABLESIZE;
}

/*
int display_picture_fullrotate(GRRLIB_texImg * jpeg, GRRLIB_texImg * pressPicImage, u8 speed, u8 fadeSpeed) {	

	int current;
	GRRLIB_DrawImg(x, y, jpeg, picturePhase, 1, 1, 0xFFFFFFFF);	
	GRRLIB_DrawImg(pressX, pressY, pressPicImage, 0, 1, 1, 0xFFFFFF00|(fadeTab[fadePhase]));	


	GRRLIB_Render();	
	
	picturePhase+=speed;
	picturePhase=picturePhase % 360;
	fadePhase+=fadeSpeed;
	fadePhase = fadePhase % FADETABLESIZE;
	
}
*/

int display_picture_fullrotate(GRRLIB_texImg * jpeg, GRRLIB_texImg * pressPicImage, u8 speed, u8 fadeSpeed) {	

	int current;
	GRRLIB_DrawImg(jpeg->offsetx+x, jpeg->offsety+y, jpeg, picturePhase, 1, 1, 0xFFFFFFFF);	
	
	do_press_pic_stuff(pressPicImage, fadePhase, pressX, pressY);
	GRRLIB_Render();	
	
	picturePhase+=speed;
	picturePhase=picturePhase % 360;
	fadePhase+=fadeSpeed;
	fadePhase = fadePhase % FADETABLESIZE;
	
}

/*---------------------------------------------------------------------------------------------*/
/*********************************** PICTURE FUNCTIONS *****************************************/



int do_intro(enum IntroEffect effect, u8 option1, u8 option2, GRRLIB_texImg * image) 
{
	switch (effect) {
		case IE_NONE : return 0; break;
		case IE_FADEIN : return display_intro_fade_in(image, option1, option2); break;
		case IE_BANDUP : return display_intro_band_up(image, option1, option2); break;
		case IE_BANDDOWN : return display_intro_band_down(image, option1, option2); break;
		case IE_ENLARGE_IN : return display_intro_enlarge_in(image, option1, option2); break;						
		case IE_ALTERNATE_LINES : return display_intro_alternate_lines(image, option1, option2);break;
		case IE_STRIPES_UP: return display_intro_stripes_up(image, option1, option2);break;		
	}
	return 0;
}

int do_picture(enum PictureEffect effect, u8 option1, u8 option2, GRRLIB_texImg * image, GRRLIB_texImg * pressImage) 
{
	switch (effect) {
		case PE_NONE : return display_jpeg(image); break;
		case PE_PRESS_PIC_FADE : return display_with_press_pic_fade(image, pressImage, option1, option2); break;
		case PE_WOBBLE : return display_picture_wobble(image, option1, option2); break;
		case PE_SCROLLX : return display_picture_scrollx(image, option1, option2); break;
		case PE_ENLARGE_XY : return display_picture_enlarge_xy(image, option1, option2); break;
		case PE_ENLARGE : return display_picture_enlarge(image, option1, option2); break;		
		case PE_IN_OUT_ROTATE : return display_picture_zoom_in_out_rotate(image, option1, option2); break;
		case PE_ZOOM_IN_OUT : return display_picture_zoominout(image, option1, option2); break;
		case PE_SINUS_ROTATE : return display_picture_sinusrotate(image, pressImage, option1, option2); break;
		case PE_FULL_ROTATE : return display_picture_fullrotate(image, pressImage, option1, option2); break;	
	}

	return 0;
}

int do_outro(enum OutroEffect effect, u8 option1, u8 option2, GRRLIB_texImg * image) 
{
	switch (effect) {
		case OE_NONE : return 0; break;
		case OE_FADEOUT :  return display_jpeg_outro_fadeout(image, option1, option2); break;
		case OE_ALTERNATE_LINES :  return display_outro_alternate_lines(image, option1, option2); break;		
		case OE_BANDUP : return display_intro_band_up(image, option1, option2); break;
		case OE_BANDDOWN : return display_intro_band_down(image, option1, option2); break;		
	}
	return 0;
}

int do_picture_stuff(int type, int effect, u8 option1, u8 option2, GRRLIB_texImg * image, GRRLIB_texImg * pressImage) 
{
	switch (type) {	
		case ET_INTRO : return do_intro(effect, option1, option2, image); break;
		case ET_PICTURE : return do_picture(effect, option1, option2, image, pressImage); break;
		case ET_OUTRO : return do_outro(effect, option1, option2, image); break;					
		
	}
	
	return 0;
}




char txt1[22][17*9]=
{"\
#################\
#    WELCOME    #\
# TO CRAZYINTRO #\
#               #\
#  BY           #\
#    WIICRAZY   #\
# AKA I.R.ON    #\
#               #\
#################\
",
"\
#################\
#               #\
# THIS IS THE   #\
# DEFAULT INTRO #\
# OF CRAZYINTRO #\
#  SHAMELESSLY  #\
# STOLEN  FROM  #\
#               #\
#################\
",
"\
#################\
#  GRRLIB 4.0   #\
#   ....        #\
#               #\
#     ....      #\
#               #\
#      .....    #\
#               #\
#################\
",
"\
#################\
#################\
####         ####\
##             ##\
##     :)      ##\
##             ##\
####         ####\
#################\
#################\
",
"\
 YOU ARE SEEING  \
 THIS INTRO      \
 BECAUSE YOU     \
 EITHER DONT HAVE\
 CUSTOM STUFF ON \
 YOUR SD CARD    \
 OR YOU SIMPLY   \
 REMOVED THE CARD\
   ANYWAY...     \
",
"\
   PRESS A FOR   \
    SYSTEM MENU  \
                 \
    OR PRESS B   \
       FOR       \
     HOMEBREW    \
     CHANNEL     \
                 \
                 \
",
"\
 HOPE ORIGINAL   \
 CREATORS OF THIS\
 NIFTY TEXT      \
 INTRO DONT GET  \
 MAD AT ME       \
                 \
 THEREFORE       \
CREDITS GOES TO  \
 THE GRRLIB TEAM!\
",
"\
   PRESS A FOR   \
    SYSTEM MENU  \
                 \
    OR PRESS B   \
       FOR       \
     HOMEBREW    \
     CHANNEL     \
                 \
                 \
",
"\
 MUSIC :         \
 ELYSIUM         \
       BY        \
                 \
 JESPER OF       \
          SANITY \
                 \
                 \
                 \
"
,
"\
 MY HUGE THANKS  \
 GOES TO         \
                 \
 CREDIAR FOR     \
 (PRELOADER)     \
 GRRLIB TEAM AND \
 TEKWARRIOR FOR  \
 (SYSLOG DAEMON) \
                 \
",
"\
 NOW LET ME      \
 DEMONSTRATE THE \
 PICTURE EFFECTS \
 TO YOU, SOME    \
 NICE, SOME UGLY \
                 \
 LET'S START WITH\
    WOBBLE       \
    EFFECT       \
",
"\
#################\
#               #\
#   AND         #\
#      HERE IS  #\
#  SINUS        #\
#      ROTATE   #\
#               #\
#               #\
#################\
",
"\
#################\
#               #\
#   THIS IS     #\
#     THE       #\
#   ENLARGE     #\
#    EFFECT     #\
# NOT SO        #\
#      NICE :P  #\
#################\
",
"\
#################\
#               #\
#   SCROLL X    #\
#               #\
#    EFFECT     #\
#               #\
#               #\
#               #\
#################\
",
"\
#################\
#               #\
#  ENLARGE X-Y  #\
#               #\
#    EFFECT     #\
#               #\
#  THIS TOO :P  #\
#               #\
#################\
",
"\
#################\
#               #\
#  IN OUT       #\
#     ROTATE    #\
#     EFFECT    #\
#               #\
#               #\
#               #\
#################\
",
"\
#################\
#               #\
#   THEN        #\
#  ZOOM IN AND  #\
#  OUT EFFECT   #\
#               #\
#               #\
#               #\
#################\
",
"\
#################\
#               #\
#  AND FINALLY  #\
#               #\
#  FULL ROTATE  #\
#               #\
#    EFFECT     #\
#               #\
#################\
",
"\
#################\
# SOME OF THE   #\
# EFFECTS MAY   #\
# SEEM LAME     #\
# WITH THIS     #\
# DEFAULT BOOT  #\
# PICTURE USED  #\
#               #\
#################\
",
"\
#################\
# BUT SINCE YOU #\
# CAN USE YOUR  #\
# OWN PICTURES  #\
# WITH THIS     #\
# STUFF, HOPE U #\
# CAN DO SOME   #\
# COOL INTROS!  #\
#################\
",
"\
#################\
# AND NOT BUT   #\
# DEMONSTRATED  #\
# ARE INTRO AND #\
# OUTRO EFFECTS #\
# YOU CAN HAVE  #\
# THEM          #\
# CUSTOMIZED TOO#\
#################\
",
"\
#################\
# AND FINALLY   #\
#               #\
# THIS IS A     #\
# PUBLIC BETA   #\
#               #\
# SO            #\
# EXPECT BUGS!  #\
#################\
"

};

int tab1[5][17*9]={
{
  0, 17, 18, 35, 36, 53, 54, 71, 72, 89, 90,107,108,125,126,143,144,
  1, 16, 19, 34, 37, 52, 55, 70, 73, 88, 91,106,109,124,127,142,145,
  2, 15, 20, 33, 38, 51, 56, 69, 74, 87, 92,105,110,123,128,141,146,
  3, 14, 21, 32, 39, 50, 57, 68, 75, 86, 93,104,111,122,129,140,147,
  4, 13, 22, 31, 40, 49, 58, 67, 76, 85, 94,103,112,121,130,139,148,
  5, 12, 23, 30, 41, 48, 59, 66, 77, 84, 95,102,113,120,131,138,149,
  6, 11, 24, 29, 42, 47, 60, 65, 78, 83, 96,101,114,119,132,137,150,
  7, 10, 25, 28, 43, 46, 61, 64, 79, 82, 97,100,115,118,133,136,151,
  8,  9, 26, 27, 44, 45, 62, 63, 80, 81, 98, 99,116,117,134,135,152

},
{
152,135,134,117,116, 99, 98, 81, 80, 63, 62, 45, 44, 27, 26,  9,  8,
151,136,133,118,115,100, 97, 82, 79, 64, 61, 46, 43, 28, 25, 10,  7,
150,137,132,119,114,101, 96, 83, 78, 65, 60, 47, 42, 29, 24, 11,  6,
149,138,131,120,113,102, 95, 84, 77, 66, 59, 48, 41, 30, 23, 12,  5,
148,139,130,121,112,103, 94, 85, 76, 67, 58, 49, 40, 31, 22, 13,  4,
147,140,129,122,111,104, 93, 86, 75, 68, 57, 50, 39, 32, 21, 14,  3,
146,141,128,123,110,105, 92, 87, 74, 69, 56, 51, 38, 33, 20, 15,  2,
145,142,127,124,109,106, 91, 88, 73, 70, 55, 52, 37, 34, 19, 16,  1,
144,143,126,125,108,107, 90, 89, 72, 71, 54, 53, 36, 35, 18, 17,  0

},
{
  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 17,
 46, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100, 63, 18,
 45, 86,119,120,121,122,123,124,125,126,127,128,129,130,101, 64, 19,
 44, 85,118,143,144,145,146,147,148,149,150,151,152,131,102, 65, 20,
 43, 84,117,142,141,140,139,138,137,136,135,134,133,132,103, 66, 21,
 42, 83,116,115,114,113,112,111,110,109,108,107,106,105,104, 67, 22,
 41, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 23,
 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24

},
{
136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,
135,134,133,132,131,130,129,128,127,126,125,124,123,122,121,120,119,
102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,
101,100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85,
 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51,
 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17,
  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16
},
{
  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17,
 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51,
 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
101,100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85,
102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,
135,134,133,132,131,130,129,128,127,126,125,124,123,122,121,120,119,
136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152
}
};


Mtx GXmodelView2D;
u32 wpaddown;
MODPlay snd1;

GRRLIB_texImg * tex_font;
GRRLIB_texImg * tex_console;
GRRLIB_texImg * boot_logo;
GRRLIB_texImg * press_img;

GRRLIB_texImg * wiimote_pic;




guVector start[NBCHAR];
guVector current[NBCHAR];
guVector final[NBCHAR];
guVector factor[NBCHAR];

float xd[5][1289],yd[5][1289];

int step=1;
int timer=0,zsens=0;

float fj=0;
float sina;
float cosa;
float sinb;
float cosb;
float sinc;
float cosc;

float c;
float nsx,nsy;

void setDefaults(bool customIntro, 
				int boot_x, 
				int boot_y, 
				int press_pic_x, 
				int press_pic_y,  
				int boot_logo_width,
				int press_pic_image_effect, 
				int press_pic_tile_width, 
				int press_pic_tile_height, 
				int press_pic_tile_ordering , 
				int press_pic_animation_speed,
				int press_pic_scale) 
{
	if (customIntro) {
		x = boot_x;
		y = boot_y;		
		pressX = press_pic_x;
		pressY = press_pic_y;			
		tileCount = boot_logo_width / TILEHEIGHT;
		int left = boot_logo_width % TILEHEIGHT;
		if (left!=0) 
		{
			tileCount++;
		}
		
		ixlateStep  = (TEARTABLESIZE/tileCount );	

		pressImageEffect = press_pic_image_effect;
		pressImageTileWidth = press_pic_tile_width;
		pressImageTileHeight = press_pic_tile_height;
		pressImageTileOrdering = press_pic_tile_ordering;
		pressImageAnimationSpeed = press_pic_animation_speed;
		pressImageScale = press_pic_scale;
		#ifdef DEBUG 
			Syslog_Send(syslog, SYSLOG_PRI_INTERNAL, SYSLOG_SEV_DEBUG, "syslog: Custom defaults");
		#endif	
		
	} else 
	{
		x=120;
		y=40;
		pressX = 425;
		pressY = 400;
		//x=10;
		//y=100;
		//pressX=220;
		//pressY=440;
		#ifdef DEBUG 
			Syslog_Send(syslog, SYSLOG_PRI_INTERNAL, SYSLOG_SEV_DEBUG, "syslog: Setting defaults");
		#endif	
		
	}
	
	
	#ifdef DEBUG 
		Syslog_Send(syslog, SYSLOG_PRI_INTERNAL, SYSLOG_SEV_DEBUG, "syslog: Making Sinus table");
	#endif	
	makeSinTab();

	#ifdef DEBUG 
		Syslog_Send(syslog, SYSLOG_PRI_INTERNAL, SYSLOG_SEV_DEBUG, "syslog: Making Cosinus table");
	#endif	

	makeCosTab();

	#ifdef DEBUG 
		Syslog_Send(syslog, SYSLOG_PRI_INTERNAL, SYSLOG_SEV_DEBUG, "syslog: Making High Res Cosinus table");
	#endif	
	
	makeHighCosTab();
	
	#ifdef DEBUG 
		Syslog_Send(syslog, SYSLOG_PRI_INTERNAL, SYSLOG_SEV_DEBUG, "syslog: Making fade table");
	#endif	
	
	makeFadeTab();

	#ifdef DEBUG 
		Syslog_Send(syslog, SYSLOG_PRI_INTERNAL, SYSLOG_SEV_DEBUG, "syslog: Making tear table");
	#endif	
	
	makeTearTab();
	#ifdef DEBUG 
	Syslog_Send(syslog, SYSLOG_PRI_INTERNAL, SYSLOG_SEV_DEBUG, "syslog: Stuff Initialized");	
	#endif
}


void setBirthdayDefaults(bool customBirthday, int offsetX, int offsetY) 
{
	if (customBirthday) {
		birthDayX = offsetX;
		birthDayY = offsetY;		
	} else 
	{
		birthDayX=100;
		birthDayY=50;
	}	
}


void InitFont() 
{
    tex_font = GRRLIB_LoadTexture(font);
    GRRLIB_InitTileSet(tex_font, 32, 33, 32);	
}

void InitDefault(){
    int i,j;
    int tmpx,tmpy;
	
#ifdef DEBUG
	Syslog_Send(syslog, SYSLOG_PRI_LOCAL0, SYSLOG_SEV_DEBUG, "Loading default pictures");
#endif

    tex_console = GRRLIB_LoadTexture(console);
    GRRLIB_InitTileSet(tex_console, 8, 8, 0);
	
	//boot_logo =  GRRLIB_LoadTexture(boot);
	boot_logo =  GRRLIB_LoadTexture(boot);

#ifdef DEBUG
	Syslog_SendFormat(syslog, SYSLOG_PRI_LOCAL0, SYSLOG_SEV_DEBUG, "boot logo is null?: %s", boot_logo==NULL ? "yes" : "no");
#endif
	
	//wiimote_pic =  GRRLIB_LoadTexture(wiimotegfx);
	
	GRRLIB_InitTileSet(boot_logo, boot_logo->w, TILEHEIGHT, 0); //Offset 0, height/TILEHEIGHT tiles each with TILEHEIGHT pixel widths
	GRRLIB_SetMidHandle(boot_logo, true);
	tileCount = boot_logo->w / TILEHEIGHT;
	ixlateStep  = (TEARTABLESIZE/tileCount );	
			
	press_img =  GRRLIB_LoadTexture(press);
	
	// Start positions precalculation
    for(i=0;i<NBCHAR;i++){
        start[i].x=-320;
        start[i].y=-240;
        start[i].z=0;
     }

// final positions precalculation
    tmpx=((640-(17*32))/2)-640;
    tmpy=((480-(9*33))/2)-480;
    for(i=0;i<NBCHAR;i++){
        final[i].x=tmpx;
        final[i].y=tmpy;
        final[i].z=1;
        tmpx+=32;
        if(tmpx>=(((640-(17*32))/2)-640)+17*32){
            tmpx=((640-(17*32))/2)-640;
            tmpy+=33;
        }
    }

// Factors precalculation
    for(i=0;i<NBCHAR;i++){
        factor[i].x = (start[i].x-final[i].x)/SPEED;
        factor[i].y = (start[i].y-final[i].y)/SPEED;
        factor[i].z = (start[i].z-final[i].z)/SPEED;
    }

    for(i=0;i<NBCHAR;i++){
        current[i].x=start[i].x;
        current[i].y=start[i].y;
        current[i].z=start[i].z;
    }

}

void Raster(){
}

void Letter(int txt,int fx,int stepper){
    int i;

    for(i=0;i<NBCHAR;i++){
        if(zsens==0){
            if(current[i].z<1){
                if(fj>tab1[fx][i]){
                    current[i].x-=factor[i].x;
                    current[i].y-=factor[i].y;
                    current[i].z-=factor[i].z;
                }
            }
            else{
                timer+=1;
                if(timer>40000){
                    timer=0;
                    zsens=1;
                }
            }
        }
        else{
            current[i].x+=factor[i].x;
            current[i].y+=factor[i].y;
            current[i].z+=factor[i].z;
            if(current[i].z < 0){
                step=stepper;
                fj=0;
                zsens=0;
                for(i=0;i<NBCHAR;i++){
                    current[i].x=start[i].x;
                    current[i].y=start[i].y;
                    current[i].z=start[i].z;
                }
            }
        }
        GRRLIB_DrawTile(current[i].x+640+5, current[i].y+480+5, tex_font, 0,current[i].z,current[i].z,0x00000000|(int)(0x88*current[i].z), txt1[txt][i]-32);
        GRRLIB_DrawTile(current[i].x+640, current[i].y+480, tex_font, 0,current[i].z,current[i].z,0xFFFFFF00|(int)(0xff*current[i].z), txt1[txt][i]-32);
    }
    fj++;
}

void StartDefaultIntroMusic() 
{

	#ifdef DEBUG 
		Syslog_Send(syslog, SYSLOG_PRI_INTERNAL, SYSLOG_SEV_DEBUG, "syslog: Initting default intro music");
	#endif	
	ASND_Init();
    MODPlay_Init(&snd1);
    MODPlay_SetMOD(&snd1, elysium);
    InitDefault();
    MODPlay_Start(&snd1);    
	#ifdef DEBUG 
		Syslog_Send(syslog, SYSLOG_PRI_INTERNAL, SYSLOG_SEV_DEBUG, "syslog: Starting default intro music");
	#endif	
	
}

void ShutdownDefaultIntro() 
{
	MODPlay_Stop(&snd1);
	GRRLIB_Exit(); // Be a good boy, clear the memory allocated by GRRLIB
}



GRRLIB_texImg * birthday_img;
MODPlay happyBirthdayMusic;

void InitDefaultBirthday() 
{
    birthday_img = GRRLIB_LoadTexture(birthday);	
	GRRLIB_SetMidHandle(birthday_img, true);
	ASND_Init();
    MODPlay_Init(&happyBirthdayMusic);
    MODPlay_SetMOD(&happyBirthdayMusic, happybirthday);
    MODPlay_Start(&happyBirthdayMusic);   
}

int birthdayPhase = -640;
int singleshot = 128;
int do_birthday_stuff(GRRLIB_texImg * img, int miiCount, GRRLIB_texImg * miis[], char * greeting) {	

	GRRLIB_FillScreen(0xFFFFFFFF);
	
	if (singleshot>8) {
		GRRLIB_DrawImg(img->offsetx+birthDayX, img->offsety+birthDayY, img, 0, 8.0/(singleshot), 8.0/(singleshot), 0xFFFFFFFF);	
		singleshot--;
	} else 
	{
		GRRLIB_DrawImg(img->offsetx+birthDayX, img->offsety+birthDayY, img, 0, 1, 1, 0xFFFFFFFF);	
		int i;
		for (i=0;i<miiCount;i++) 
		{
			GRRLIB_DrawImg(birthDayX-birthdayPhase+i*115, 280, miis[i], 0, 1, 1, 0xFFFFFFFF);
		}
		
		GRRLIB_Printf(birthDayX-birthdayPhase+miiCount*115+40, 400, tex_font, 0xFFA500FF, 1, greeting);
	
		birthdayPhase+=2;
	
		if (birthdayPhase == (600 + miiCount*400)) 
		{
			birthdayPhase = -640;
		}
	}
}


void do_default_birthday_stuff(int miiCount, GRRLIB_texImg * miis[], char * greeting) 
{
	do_birthday_stuff(birthday_img, miiCount, miis, greeting);
/*
	GRRLIB_FillScreen(0xFFFFFFFF);
	
	if (singleshot>8) {
		GRRLIB_DrawImg(birthday_img->offsetx+birthDayX, birthday_img->offsety+ birthDayY, birthday_img, 0, 8.0/(singleshot), 8.0/(singleshot), 0xFFFFFFFF);	
		singleshot--;
	} else 
	{
		GRRLIB_DrawImg(birthday_img->offsetx+birthDayX, birthday_img->offsety+birthDayY, birthday_img, 0, 1, 1, 0xFFFFFFFF);	
		
		GRRLIB_Printf(birthDayX-birthdayPhase+miiCount*115+40, 400, tex_font, 0xFFA500FF, 1, greeting);
	
		birthdayPhase+=2;
	
		if (birthdayPhase == 1000) 
		{
			birthdayPhase = -640;
		}
	}
*/
}

void FinishDefaultBirthdayStuff()  
{
	int i;
	for (i=255;i>=0;i-=5) 
	{
		ASND_ChangeVolumeVoice(0, i, i);
		usleep(50000);
	}
	MODPlay_Stop(&happyBirthdayMusic);
}

static int dPhase1 = 0;
static int dPhase2 = 0;
static int dPhase3 = 0;
static int dPhase4 = 255;
static int dPhase5 = 0;
static int dPhase6 = 0;
static int dPhase7 = 0;
static int dPhase8 = 0;
static int dPhase9 = 0;
static int dPhase10 = 0;
static int dPhase11 = 0;
static int dPhase12 = 0;
static int dPhase13 = 0;
static int dPhase14 = 0;
static int dPhase15 = 0;
static int loop1 = 0;
static int iStep = 1;

//Let's make this one iteration based too... All this is to prevent keycheck and exit code duplication
//Also this will allow me to put picture effects here easily

void do_default_picture_stuff() 
{
	//Default Intro Phase 1
	//Fade in the default boot image
	switch (iStep) 
	{
	case 1 :
		#ifdef DEBUG 
		//Syslog_Send(syslog, SYSLOG_PRI_INTERNAL, SYSLOG_SEV_DEBUG, "syslog: Case 1");
		#endif	

		if (dPhase1<255) 
		{
			GRRLIB_DrawImg(boot_logo->offsetx+x, boot_logo->offsety+y, boot_logo, 0, 1, 1, 0xFFFFFF00|dPhase1);
			GRRLIB_Render();	
			dPhase1++;
		} else {
			iStep++; //Go to next step
			dPhase1 = 0; //Make it clean for the next call to this step.
		}
		break;
	case 2 : //Press pic display fadein phase
		#ifdef DEBUG 
		//Syslog_Send(syslog, SYSLOG_PRI_INTERNAL, SYSLOG_SEV_DEBUG, "syslog: Case 2");
		#endif	
	
		if (dPhase2<255)
		{
			GRRLIB_DrawImg(boot_logo->offsetx+x, boot_logo->offsety+y, boot_logo, 0, 1, 1, 0xFFFFFFFF);
			GRRLIB_DrawImg(pressX, pressY, press_img, 0, 1, 1, 0xFFFFFF00|dPhase2);
			GRRLIB_Render();
			dPhase2+=3;
		} else {
			iStep++;
			dPhase2=0;
		}
		break;
	case 3 : //Press pic display fadeout phase
		#ifdef DEBUG 
		//Syslog_Send(syslog, SYSLOG_PRI_INTERNAL, SYSLOG_SEV_DEBUG, "syslog: Case 3");
		#endif	
	
		if (dPhase3<255)
		{
			GRRLIB_DrawImg(boot_logo->offsetx+x, boot_logo->offsety+y, boot_logo, 0, 1, 1, 0xFFFFFFFF);		
			GRRLIB_DrawImg(pressX, pressY, press_img, 0, 1, 1, 0xFFFFFF00|(255-dPhase3));
			GRRLIB_Render();
			dPhase3+=3;
		} else {
			if (loop1<4) {
				iStep=2; //Repeat phase 2 & 3 (5 times)
				dPhase3=0;
				loop1++;
			} else {
				iStep++; //Ok repeated enough then next step
				dPhase3=0;
				loop1=0; //Set to 0 so next time we loop again
			}
		} 
		break;
	case 4 : //Fade out the boot logo
		#ifdef DEBUG 
		//Syslog_Send(syslog, SYSLOG_PRI_INTERNAL, SYSLOG_SEV_DEBUG, "syslog: Case 4");
		#endif	
	
		if (dPhase4>=0) 
		{
			GRRLIB_DrawImg(boot_logo->offsetx+x, boot_logo->offsety+y, boot_logo, 0, 1, 1, 0xFFFFFF00|dPhase4);
			GRRLIB_Render();	
			dPhase4-=5;
		} else {
			//iStep++; //Go to next step
			dPhase4 = 255; //Make it clean for the next call to this step.
			iStep++;
		}
		break;	

	case 5 : //Print
		if (step!=2) {
			Letter(0,1,step+1);
			//do_picture_stuff(ET_PICTURE, PE_SINUS_ROTATE, 2 ,3, boot_logo,press_img); 
			GRRLIB_Render();
		} else 
		{
			iStep++;
		}
		break;	
		
	case 6 : //Print
		if (step!=3) {
			Letter(1,4,step+1);
			GRRLIB_Render();
		} else 
		{
			iStep++;
		}
		break;	


	case 7 : //Print
		if (step!=4) {
			Letter(2,2,step+1);
			GRRLIB_Render();
		} else 
		{
			iStep++;
		}
		break;	
		
	case 8 : //Print
		if (step!=5) {
			Letter(3,1,step+1);
			GRRLIB_Render();
		} else 
		{
			iStep++;
		}
		break;	

	case 9 : //Print
		if (step!=6) {
			Letter(4,4,step+1);
			GRRLIB_Render();
		} else 
		{
			iStep++;
		}
		break;	
		
	case 10 : //Print
		if (step!=7) {
			Letter(5,2,step+1);
			GRRLIB_Render();
		} else 
		{
			iStep++;
		}
		break;	
	case 11 : //Print
		if (step!=8) {
			Letter(6,1,step+1);
			GRRLIB_Render();
		} else 
		{
			iStep++;
		}
		break;	
		
	case 12 : //Print
		if (step!=9) {
			Letter(7,2,step+1);
			GRRLIB_Render();
		} else 
		{
			iStep++;
		}
		break;	

	case 13 : //Print
		if (step!=10) {
			Letter(8,2,step+1);
			GRRLIB_Render();
		} else 
		{
			iStep++;
		}
		break;	

	case 14 : //Print
		if (step!=11) {
			Letter(9,2,step+1);
			GRRLIB_Render();
		} else 
		{
			iStep++;
		}
		break;	

	case 15 : //Print
		if (step!=12) {
			Letter(10,2,step+1);
			GRRLIB_Render();
		} else 
		{
			iStep++;
		}
		break;	

	case 16 : //Print
		if (dPhase5<512) {
			do_picture_stuff(ET_PICTURE, PE_WOBBLE, 5 ,1, boot_logo,press_img); 
			dPhase5++;
		} else {
			dPhase5 = 0;
			picturePhase = 0;
			iStep++;
		}
		break;	

	case 17 : //Print
		if (step!=13) {
			Letter(11,2,step+1);
			GRRLIB_Render();
		} else 
		{
			iStep++;
		}
		break;	

	case 18 : //Print
		if (dPhase6<512) {
			dPhase6++;
			do_picture_stuff(ET_PICTURE, PE_SINUS_ROTATE, 2 ,3, boot_logo,press_img); 
		} else {
			dPhase6 = 0;
			picturePhase = 0;
			iStep++;
		}
		break;	

	case 19 : //Print
		if (step!=14) {
			Letter(12,1,step+1);
			GRRLIB_Render();
		} else 
		{
			iStep++;
		}
		break;	
	case 20 : //Print
		if (dPhase7<512) {
			dPhase7++;
			do_picture_stuff(ET_PICTURE, PE_ENLARGE, 2 ,0, boot_logo,press_img); 
		} else {
			dPhase7 = 0;
			picturePhase = 0;
			iStep++;
		}
		break;	
		
	case 21 : //Print
		if (step!=15) {
			Letter(13,4,step+1);
			GRRLIB_Render();
		} else 
		{
			iStep++;
		}
		break;	
	case 22 : //Print
		if (dPhase8<512) {
			dPhase8++;
			do_picture_stuff(ET_PICTURE, PE_SCROLLX, 2 ,0, boot_logo,press_img); 
		} else {
			dPhase8 = 0;
			picturePhase = 0;
			iStep++;
		}
		break;	
	case 23 : //Print
		if (step!=16) {
			Letter(14,2,step+1);
			GRRLIB_Render();
		} else 
		{
			iStep++;
		}
		break;	
	case 24 : //Print
		if (dPhase9<512) {
			dPhase9++;
			do_picture_stuff(ET_PICTURE, PE_ENLARGE_XY, 2 ,0, boot_logo,press_img); 
		} else {
			dPhase9 = 0;
			picturePhase = 0;
			iStep++;
		}
		break;			
	case 25 : //Print
		if (step!=17) {
			Letter(15,1,step+1);
			GRRLIB_Render();
		} else 
		{
			iStep++;
		}
		break;	
	case 26 : //Print
		if (dPhase10<512) {
			dPhase10++;
			do_picture_stuff(ET_PICTURE, PE_IN_OUT_ROTATE, 2 ,0, boot_logo,press_img); 
		} else {
			dPhase10 = 0;
			picturePhase = 0;
			iStep++;
		}
		break;			

	case 27 : //Print
		if (step!=18) {
			Letter(16,2,step+1);
			GRRLIB_Render();
		} else 
		{
			iStep++;
		}
		break;	
	case 28 : //Print
		if (dPhase11<512) {
			dPhase11++;
			do_picture_stuff(ET_PICTURE, PE_ZOOM_IN_OUT, 2 ,0, boot_logo,press_img); 
		} else {
			dPhase11 = 0;
			picturePhase = 0;
			iStep++;			
		}
		break;			
	case 29 : //Print
		if (step!=19) {
			Letter(17,3,step+1);
			GRRLIB_Render();
		} else 
		{
			iStep++;
		}
		break;	
	case 30 : //Print
		if (dPhase12<512) {
			dPhase12++;
			do_picture_stuff(ET_PICTURE, PE_FULL_ROTATE, 2 ,3, boot_logo,press_img); 
		} else {
			dPhase12 = 0;
			picturePhase = 0;
			iStep++;	
		}
		break;			
	case 31 : //Print
		if (step!=20) {
			Letter(18,3,step+1);
			GRRLIB_Render();
		} else 
		{
			iStep++;
		}
		break;	
	case 32 : //Print
		if (step!=21) {
			Letter(19,3,step+1);
			GRRLIB_Render();
		} else 
		{
			iStep=1;
			step++;
		}
		break;	
	case 33 : //Print
		if (step!=22) {
			Letter(20,3,step+1);
			GRRLIB_Render();
		} else 
		{
			iStep=1;
			step++;
		}
		break;	
	case 34 : //Print
		if (step!=23) {
			Letter(21,3,step+1);
			GRRLIB_Render();
		} else 
		{
			iStep=1;
			step=1;
		}
		break;	
		
		
	}

}

